function RFW.PowerShellPlayer(p, id, color, alpha)
	if not (p.mo and p.mo.valid) then return end
	if not id then print("Power-up shells MUST be spawned with an ID to work properly.") return end
	if not p.mo.shells then
		p.mo.shells = {}
	end
	if not p.mo.shells[id] then
		local shell = P_SpawnGhostMobj(p.mo)
		shell.isshell = true
		shell.shellid = id //for modders
		shell.color = color
		shell.scale = p.mo.scale*9/8
		shell.renderflags = $|RF_FULLBRIGHT|RF_NOCOLORMAPS
		shell.blendmode = AST_ADD
		shell.fuse = 2
		shell.colorized = true
		shell.dispoffset = 3
		//if shell.tracer then
		//	shell.tracer.isshell = true
		//	shell.tracer.isshelloverlay = true
		//	shell.color = color or p.mo.color
		//	shell.alpha = alpha or FU
		//	shell.tracer.renderflags = $|RF_FULLBRIGHT|RF_NOCOLORMAPS
		//	shell.tracer.blendmode = AST_ADD
		//	shell.tracer.fuse = 2
		//	shell.tracer.colorized = true
		//	shell.dispoffset = 3
		//end
		p.mo.shells[id] = shell
	else
		if color ~= nil then
			p.mo.shells[id].color = color
		end
		if alpha ~= nil then
			p.mo.shells[id].alpha = alpha
		end
		p.mo.shells[id].fuse = 2
	end
	return p.mo.shells[id]
end

addHook("MobjThinker", function(mo)
	if not mo.isshell then return end
	if not mo.target then
		P_RemoveMobj(mo)
		return
	end
	mo.scale = mo.target.scale*9/8
	if P_MobjFlip(mo.target) == -1 then
		mo.eflags = $|MFE_VERTICALFLIP
	else
		mo.eflags = $ & ~(MFE_VERTICALFLIP)
	end
	if P_MobjFlip(mo) == -1 and P_PlayerShouldUseSpinHeight(mo.target.player) then
		//print(1)
		P_MoveOrigin(mo, mo.target.x, mo.target.y, mo.target.z+mo.target.height-P_GetPlayerHeight(mo.target.player)/2-mo.height/2)
	else
		P_MoveOrigin(mo, mo.target.x, mo.target.y, mo.target.z+P_GetPlayerHeight(mo.target.player)/2-mo.height/2)
	end
	mo.skin = mo.target.skin
	mo.sprite = mo.target.sprite
	mo.frame = mo.target.frame
	mo.sprite2 = mo.target.sprite2
	mo.angle = mo.target.angle //set the remaining 3 degrees of the player
	mo.roll = mo.target.roll
	mo.spriteroll = mo.target.spriteroll
	mo.pitch = mo.target.pitch
	//mo.frame = mo.target.frame
	//mo.sprite = mo.target.sprite
end, MT_GHOST)

addHook("MobjFuse", function(mo)
	if not mo.isshell then return end
	if not mo.target then return end
	if mo.target.shells[mo.shellid] and (mo.target.shells[mo.shellid] == mo) then
		mo.target.shells[mo.shellid] = nil
	end
end, MT_GHOST)